/**
 * @fileOverview anchor
 * @author huangtonger@aliyun.com
 */
const AnchorController = require('../controller/anchor');
const Util = require('../util/');
const Mixin = {};

Mixin.CFG = {
  /**
   * @type {object}
   */
  anchor: {}
};

Mixin.INIT = '_initAnchor';
Mixin.AUGMENT = {
  _initAnchor() {
    const anchorCfg = this.get('anchor');
    const graph = this.get('_graph');
    if (anchorCfg) {
      const anchorController = new AnchorController({
        diagram: this,
        graph,
        ...anchorCfg
      });
      this.setController('anchor', anchorController);
    }
  },
  showAnchor(item, indexs, isShowHotspot) {
    const anchorController = this.getController('anchor');
    anchorController.showAnchor(item, indexs, isShowHotspot);
  },
  clearAnchor(item) {
    const anchorController = this.getController('anchor');
    anchorController.clearAnchor(item);
  },
  setHotspotActived(anchor, bool) {
    const anchorController = this.getController('anchor');
    anchorController.setHotspotActived(anchor, bool);
  },
  hoverShowAnchor(item) {
    const anchorPoints = item.getAnchorPoints();
    const showIndexs = [];
    anchorPoints.forEach((anchorPoint, index) => {
      const hoverNodeEvent = {
        anchor: anchorPoint,
        item
      };
      this.emit('hovernode:beforeshowanchor', hoverNodeEvent);
      if (!hoverNodeEvent.cancel) {
        showIndexs.push(index);
      }
    });
    this.showAnchor(item, showIndexs);
  },
  anchorHasBeenLinked(node, anchor) {
    const edges = node.getEdges();
    const linkedAnchors = [];
    edges.forEach(edge => {
      const model = edge.getModel();
      if (model.source === node.id && !Util.isNil(model.sourceAnchor)) {
        linkedAnchors.push(model.sourceAnchor);
      }
      if (model.target === node.id && !Util.isNil(model.targetAnchor)) {
        linkedAnchors.push(model.targetAnchor);
      }
    });
    if (Util.isObject(anchor)) {
      return linkedAnchors.indexOf(anchor.index) !== -1;
    }
    return linkedAnchors.indexOf(anchor) !== -1;
  },
  dragEdgeBeforeShowAnchor(inputNode, inputAnchor, dragEndPointType) {
    const graph = this.getGraph();
    const nodes = graph.getNodes();
    nodes.forEach(node => {
      const showIndexs = [];
      const anchorPoints = node.getAnchorPoints();
      let eventObj;

      if (inputNode.isNode) {
        // 如果输入端是节点
        const inputAnchorPoints = inputNode.getAnchorPoints();
        anchorPoints.forEach((anchorPoint, index) => {
          if (dragEndPointType === 'target') {
            eventObj = {
              source: inputNode,
              sourceAnchor: inputAnchorPoints[inputAnchor],
              target: node,
              targetAnchor: anchorPoint,
              dragEndPointType
            };
          } else {
            eventObj = {
              target: inputNode,
              targetAnchor: inputAnchorPoints[inputAnchor],
              source: node,
              sourceAnchor: anchorPoint,
              dragEndPointType
            };
          }
          this.emit('dragedge:beforeshowanchor', eventObj);
          if (!eventObj.cancel) {
            showIndexs.push(index);
          }
        });
      } else {
        // 如果输入端是点
        anchorPoints.forEach((anchorPoint, index) => {
          showIndexs.push(index);
        });
      }
      if (node === inputNode && node.isAnchorShow) {
        showIndexs.forEach(showIndex => {
          const anchor = node.getAnchor(showIndex);
          // 现象：在hovernode:beforeshowanchor事件中，将某个anchor.cancel设为true后，此处可能为undefined
          // 原因：getAnchor是从node.anchorShapes中检索，anchorShapes是getAnchorPoints结果的子集，所以存在找不到的情况
          (inputAnchor !== showIndex) && anchor && anchor.showHotspot();
        });
      } else {
        this.showAnchor(node, showIndexs, true);
      }
    });
  }
};
module.exports = Mixin;
